﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using MotionCS.Helper;
using MotionCS.CameraVision;
using MotionCS.Controller;
using MotionCS.Module;
using MotionCS.Alarm;
using MotionCS.Config;
using MotionCS.Enumerate;
using System.CodeDom;
using System.Data;
using MotionCS.StatusLed;

namespace MotionCS
{
    public partial class MotionLib
    {
        /// <summary>
        /// 软件版本
        /// </summary>
        private static string SoftwareVersion = "V1.0.0.1_SPI_20240811_beta";
        /// <summary>
        /// 成功
        /// </summary>
        public const int MT_OK = 0;
        /// <summary>
        /// 初始化失败
        /// </summary>
        public const int MT_INIT_FAILED = 0x70000007;
        /// <summary>
        /// 未知
        /// </summary>
        public const int MT_UNKNOWN = 0x70000003;
        /// <summary>
        /// 轴号错误
        /// </summary>
        public const int AXIS_ERR = 0x70000000;
        /// <summary>
        /// 非调试模式，无效指令
        /// </summary>
        public const int MT_CMD_INVALID = 0x70000001;
        /// <summary>
        /// 轴不支持点位运动
        /// </summary>
        public const int MT_MOVE_POINT_NOTSUP = 0x70000002;
        /// <summary>
        /// 标定保存失败
        /// </summary>
        public const int MT_CAIL_SAVE_FAILED = 0x70000004;
        /// <summary>
        /// 相机未初始化
        /// </summary>
        public const int MT_CAMERA_NOT_INIT = 0x70000005;
        /// <summary>
        /// 参数错误
        /// </summary>
        public const int MT_PARAM_ERR = 0x70000006;
        /// <summary>
        /// 主状态非空闲状态
        /// </summary>
        public const int MT_MAIN_NOT_IDLE = 0x70000007;
        /// <summary>
        /// 路径规划失败
        /// </summary>
        public const int MT_PATH_FAILED = 0x70000008;
        /// <summary>
        /// 保存参数失败
        /// </summary>
        public const int MT_SAVE_FAILED = 0x70000009;
        /// <summary>
        /// 模组禁用
        /// </summary>
        public const int MT_MODULE_DISABLE = 0x7000000A;
        /// <summary>
        /// 为准备好
        /// </summary>
        public const int MT_MODULE_NOT_READY = 0x7000000B;
        /// <summary>
        /// 启动采集失败
        /// </summary>
        public const int MT_MODULE_GRAB_FAILED = 0x7000000C;
        /// <summary>
        /// 配置类型
        /// </summary>
        public enum enConfiType
        {
            /// <summary>
            /// 传输超时时间
            /// </summary>
            TimeoutT1,
            /// <summary>
            /// 传输超时时间
            /// </summary>
            TimeoutT2
        }
        /// <summary>
        /// 返回状态
        /// </summary>
        public struct MT_Status
        {
            /// <summary>
            /// 状态代码
            /// </summary>
            public int Code;
            /// <summary>
            /// 状态信息
            /// </summary>
            public string ErrString;
        }
        /// <summary>
        /// 设备初始化
        /// </summary>
        /// <param name="imageCallback"></param>
        /// <param name="logCallback"></param>
        /// <returns></returns>
        public List<CameraConf> MT_MachineInit(Action<IFrameData> imageCallback, Action<string> logCallback)
        {
            int nRet;
            MT_Status status = new MT_Status();
            status.Code = MT_OK;
            Logger.LogCallback = logCallback;
            Logger.InitLog4Net();

       

            Logout($"电控版本:{SoftwareVersion}");
            imageDataCallback = imageCallback;

            nRet = MotionInit();
            if (nRet != 0)
            {
                status.Code = MT_INIT_FAILED;
                status.ErrString = "硬件初始化失败.";
                Logout(status.ErrString);
            }

            return cameraConfs;
        }
        /// <summary>
        /// 设备释放
        /// </summary>
        /// <returns></returns>
        public MT_Status MT_MachineDispose()
        {
            MT_Status status = new MT_Status();
            status.Code = MT_OK;

            Logout("收到释放硬件模块.");
            MotionUninit();

            return status;
        }
        /// <summary>
        /// 设备复位
        /// </summary>
        /// <returns></returns>
        public MT_Status MT_MachineReset()
        {
            MT_Status status = new MT_Status();
            status.Code = MT_OK;

            cameraConfs.ForEach(itm =>
            {
                MT_MachineReset(itm);
            });

            return status;
        }
        /// <summary>
        /// 设备复位
        /// </summary>
        /// <param name="camera"></param>
        /// <returns></returns>
        public MT_Status MT_MachineReset(CameraConf conf)
        {
            MT_Status status = new MT_Status();
            status.Code = MT_OK;

            string strLog = $"{conf.CamName}模组收到复位操作,";
            CameraModule camera = GetCameraModuleByCamNo(conf.CamNo);
            if (camera == null)
            {
                status.Code = MT_MODULE_DISABLE;
                status.ErrString = strLog + $"复位失败(相机模组未知).";
                Logout($"{status.ErrString}");
                return status;
            }
            ConveyorModule conveyor = GetConveyorModuleByCamNo(conf.CamNo);
            if (conveyor == null)
            {
                status.Code = MT_MODULE_DISABLE;
                status.ErrString = strLog + $"复位失败(轨道模组未知)";
                Logout($"{status.ErrString}");
                return status;
            }

            if (camera.ResetStart() != 0)
            {
                status.Code = MT_CMD_INVALID;
                status.ErrString = strLog + $"复位失败(相机模组当前状态不支持)";
                Logout($"{status.ErrString}");
                return status;
            }

            if (conveyor.ResetStart(false) != 0)
            {
                status.Code = MT_CMD_INVALID;
                status.ErrString = strLog + $"复位失败(轨道模组当前状态不支持)";
                Logout($"{status.ErrString}");
                return status;
            }

            return status;
        }
        /// <summary>
        /// 轴移动到绝对位置
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="fpos"></param>
        /// <returns></returns>
        public MT_Status MT_MoveAbs(CameraConf camConf, AxisE axis, float fpos)
        {
            MT_Status status = new MT_Status();
            status.Code = MT_OK;

            string strLog = $"{camConf.CamName}模组{axis}轴收到绝对运动到位置: {fpos},";
            switch (axis)
            {
                case AxisE.X:
                case AxisE.Y:
                    CameraModule camera = GetCameraModuleByCamNo(camConf.CamNo);
                    if (camera == null)
                    {
                        status.Code = MT_MODULE_DISABLE;
                        status.ErrString = strLog + $"运动失败(模组未知).";
                        Logout($"{status.ErrString}");
                        return status;
                    }

                    if (camera.ModuleTaskState() != ModuleTaskStateE.Idle)
                    {
                        status.Code = MT_CMD_INVALID;
                        status.ErrString = strLog + $"运动失败(模组非空闲状态)";
                        Logout($"{status.ErrString}");
                        return status;
                    }

                    if (axis == AxisE.X)
                    {
                        if (!camera.AxisX.IsCheckDone())
                        {
                            status.Code = MT_CMD_INVALID;
                            status.ErrString = strLog + $"运动失败(运动未停止)";
                            Logout($"{status.ErrString}");
                            return status;
                        }
                        camera.AxisX.SetMualSpeed();
                        if (0 != camera.AxisX.MoveAbs(fpos))
                        {
                            status.Code = MT_MOVE_POINT_NOTSUP;
                            status.ErrString = strLog + $"运动失败(软件限位)";
                            Logout($"{status.ErrString}");
                            return status;
                        }
                    }
                    if (axis == AxisE.Y)
                    {
                        if (!camera.AxisY.IsCheckDone())
                        {
                            status.Code = MT_CMD_INVALID;
                            status.ErrString = strLog + $"运动失败(运动未停止)";
                            Logout($"{status.ErrString}");
                            return status;
                        }
                        camera.AxisY.SetMualSpeed();
                        if (0 != camera.AxisY.MoveAbs(fpos))
                        {
                            status.Code = MT_MOVE_POINT_NOTSUP;
                            status.ErrString = strLog + $"运动失败(软件限位)";
                            Logout($"{status.ErrString}");
                            return status;
                        }
                    }
                    break;
                case AxisE.T:
                case AxisE.W:
                    ConveyorModule conveyor = GetConveyorModuleByCamNo(camConf.CamNo);
                    if (conveyor == null)
                    {
                        status.Code = MT_MODULE_DISABLE;
                        status.ErrString = strLog + $"运动失败(模组未知)";
                        Logout($"{status.ErrString}");
                        return status;
                    }
                    if (conveyor.ModuleTaskState() != ModuleTaskStateE.Idle)
                    {
                        status.Code = MT_CMD_INVALID;
                        status.ErrString = strLog + $"运动失败(模组非空闲状态)";
                        Logout($"{status.ErrString}");
                        return status;
                    }
                    if (axis == AxisE.T)
                    {
                        conveyor.AxisT.SetMualSpeed();
                        if (0 != conveyor.AxisT.MoveAbs(fpos))
                        {
                            status.Code = MT_MOVE_POINT_NOTSUP;
                            status.ErrString = strLog + $"运动失败(不支持位置模式)";
                            Logout($"{status.ErrString}");
                            return status;
                        }
                    }
                    if (axis == AxisE.W)
                    {
                        if (conveyor.IsHasBoard())
                        {
                            status.Code = MT_CMD_INVALID;
                            status.ErrString = strLog + $"运动失败(传送带有板)";
                            Logout($"{status.ErrString}");
                            return status;
                        }
                        if (!conveyor.AxisW.IsCheckDone())
                        {
                            status.Code = MT_CMD_INVALID;
                            status.ErrString = strLog + $"运动失败(运动未停止)";
                            Logout($"{status.ErrString}");
                            return status;
                        }
                        conveyor.AxisW.SetMualSpeed();
                        if (0 != conveyor.AxisW.MoveAbs(fpos))
                        {
                            status.Code = MT_MOVE_POINT_NOTSUP;
                            status.ErrString = strLog + $"运动失败(软件限位)";
                            Logout($"{status.ErrString}");
                            return status;
                        }
                        conveyor.SaveAxisWPosition();
                    }
                    break;
                default:
                    break;
            }

            Logout(strLog);
            return status;
        }
        /// <summary>
        /// 轴移动到相对位置
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="fpos"></param>
        /// <returns></returns>
        public MT_Status MT_MoveRel(CameraConf camConf, AxisE axis, float fpos)
        {
            MT_Status status = new MT_Status();
            status.Code = MT_OK;

            string strLog = $"{camConf.CamName}模组{axis}轴收到相对运动到位置: {fpos},";
            switch (axis)
            {
                case AxisE.X:
                case AxisE.Y:
                    CameraModule camera = GetCameraModuleByCamNo(camConf.CamNo);
                    if (camera == null)
                    {
                        status.Code = MT_MODULE_DISABLE;
                        status.ErrString = strLog + $"运动失败(模组未知).";
                        Logout($"{status.ErrString}");
                        return status;
                    }

                    if (camera.ModuleTaskState() != ModuleTaskStateE.Idle)
                    {
                        status.Code = MT_CMD_INVALID;
                        status.ErrString = strLog + $"运动失败(模组非空闲状态)";
                        Logout($"{status.ErrString}");
                        return status;
                    }
                    if (axis == AxisE.X)
                    {
                        if (!camera.AxisX.IsCheckDone())
                        {
                            status.Code = MT_CMD_INVALID;
                            status.ErrString = strLog + $"运动失败(运动未停止)";
                            Logout($"{status.ErrString}");
                            return status;
                        }

                        camera.AxisX.SetMualSpeed();
                        if (0 != camera.AxisX.MoveRel(fpos))
                        {
                            status.Code = MT_MOVE_POINT_NOTSUP;
                            status.ErrString = strLog + $"运动失败(软件限位)";
                            Logout($"{status.ErrString}");
                            return status;
                        }
                    }
                    if (axis == AxisE.Y)
                    {
                        if (!camera.AxisY.IsCheckDone())
                        {
                            status.Code = MT_CMD_INVALID;
                            status.ErrString = strLog + $"运动失败(运动未停止)";
                            Logout($"{status.ErrString}");
                            return status;
                        }

                        camera.AxisY.SetMualSpeed();
                        if (0 != camera.AxisY.MoveRel(fpos))
                        {
                            status.Code = MT_MOVE_POINT_NOTSUP;
                            status.ErrString = strLog + $"运动失败(软件限位)";
                            Logout($"{status.ErrString}");
                            return status;
                        }
                    }
                    break;
                case AxisE.T:
                case AxisE.W:
                    ConveyorModule conveyor = GetConveyorModuleByCamNo(camConf.CamNo);
                    if (conveyor == null)
                    {
                        status.Code = MT_MODULE_DISABLE;
                        status.ErrString = strLog + $"运动失败(模组未知)";
                        Logout($"{status.ErrString}");
                        return status;
                    }
                    if (conveyor.ModuleTaskState() != ModuleTaskStateE.Idle)
                    {
                        status.Code = MT_CMD_INVALID;
                        status.ErrString = strLog + $"运动失败(模组非空闲状态)";
                        Logout($"{status.ErrString}");
                        return status;
                    }
                    if (axis == AxisE.T)
                    {
                        conveyor.AxisT.SetMualSpeed();
                        if (0 != conveyor.AxisT.MoveRel(fpos))
                        {
                            status.Code = MT_MOVE_POINT_NOTSUP;
                            status.ErrString = strLog + $"运动失败(不支持位置模式)";
                            Logout($"{status.ErrString}");
                            return status;
                        }
                    }
                    if (axis == AxisE.W)
                    {
                        if (conveyor.IsHasBoard())
                        {
                            status.Code = MT_CMD_INVALID;
                            status.ErrString = strLog + $"运动失败(传送带有板)";
                            Logout($"{status.ErrString}");
                            return status;
                        }

                        if (!conveyor.AxisW.IsCheckDone())
                        {
                            status.Code = MT_CMD_INVALID;
                            status.ErrString = strLog + $"运动失败(运动未停止)";
                            Logout($"{status.ErrString}");
                            return status;
                        }

                        conveyor.AxisW.SetMualSpeed();
                        if (0 != conveyor.AxisW.MoveRel(fpos))
                        {
                            status.Code = MT_MOVE_POINT_NOTSUP;
                            status.ErrString = strLog + $"运动失败(软件限位)";
                            Logout($"{status.ErrString}");
                            return status;
                        }

                        conveyor.SaveAxisWPosition();
                    }
                    break;
                default:
                    break;
            }

            Logout(strLog);
            return status;
        }
        /// <summary>
        /// 轴方向持续运动
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="dir">1-正向，-1-负向</param>
        /// <returns></returns>
        public MT_Status MT_MoveDir(CameraConf camConf, AxisE axis, int dir)
        {
            MT_Status status = new MT_Status();
            status.Code = MT_OK;
            string strDir = dir == -1 ? "负向" : "正向";
            string strLog = $"{camConf.CamName}模组{axis}轴收到{strDir}运动,";
            switch (axis)
            {
                case AxisE.X:
                case AxisE.Y:
                    CameraModule camera = GetCameraModuleByCamNo(camConf.CamNo);
                    if (camera == null)
                    {
                        status.Code = MT_MODULE_DISABLE;
                        status.ErrString = strLog + $"运动失败(模组未知).";
                        Logout($"{status.ErrString}");
                        return status;
                    }

                    if (camera.ModuleTaskState() != ModuleTaskStateE.Idle)
                    {
                        status.Code = MT_CMD_INVALID;
                        status.ErrString = strLog + $"运动失败(模组非空闲状态)";
                        Logout($"{status.ErrString}");
                        return status;
                    }
                    if (axis == AxisE.X)
                    {
                        camera.AxisX.SetMualSpeed();
                        if (dir == 1)
                        {
                            camera.AxisX.MoveForward();
                        }
                        if (dir == -1)
                        { 
                            camera.AxisX.MoveBackward(); 
                        }
                    }
                    if (axis == AxisE.Y)
                    {
                        camera.AxisY.SetMualSpeed();
                        if (dir == 1)
                        {
                            camera.AxisY.MoveForward();
                        }
                        if (dir == -1)
                        {
                            camera.AxisY.MoveBackward();
                        }
                    }
                    break;
                case AxisE.T:
                case AxisE.W:
                    ConveyorModule conveyor = GetConveyorModuleByCamNo(camConf.CamNo);
                    if (conveyor == null)
                    {
                        status.Code = MT_MODULE_DISABLE;
                        status.ErrString = strLog + $"运动失败(模组未知)";
                        Logout($"{status.ErrString}");
                        return status;
                    }
                    if (conveyor.ModuleTaskState() != ModuleTaskStateE.Idle)
                    {
                        status.Code = MT_CMD_INVALID;
                        status.ErrString = strLog + $"运动失败(模组非空闲状态)";
                        Logout($"{status.ErrString}");
                        return status;
                    }
                    if (axis == AxisE.T)
                    {
                        conveyor.AxisT.SetMualSpeed();
                        if (dir == 1)
                        {
                            conveyor.AxisT.MoveForward();
                        }
                        if (dir == -1)
                        {
                            conveyor.AxisT.MoveBackward();
                        }
                    }
                    if (axis == AxisE.W)
                    {
                        if (conveyor.IsHasBoard())
                        {
                            status.Code = MT_CMD_INVALID;
                            status.ErrString = strLog + $"运动失败(传送带有板)";
                            Logout($"{status.ErrString}");
                            return status;
                        }

                       // conveyor.AxisW.SetMualSpeed();
                        conveyor.AxisW.SetAutoSpeed2();
                        if (dir == 1)
                        {
                            conveyor.AxisW.MoveForward();
                        }
                        if (dir == -1)
                        {
                            conveyor.AxisW.MoveBackward();
                        }

                        conveyor.SaveAxisWPosition();
                    }
                    break;
                default:
                    break;
            }

            Logout(strLog);
            return status;           
        }
        /// <summary>
        /// 轴停止运动
        /// </summary>
        /// <param name="axis"></param>
        /// <returns></returns>
        public MT_Status MT_MoveStop(CameraConf camConf, AxisE axis)
        {
            MT_Status status = new MT_Status();
            status.Code = MT_OK;
            string strLog = $"{camConf.CamName}模组{axis}轴收到停止运动,";
            switch (axis)
            {
                case AxisE.X:
                case AxisE.Y:
                    CameraModule camera = GetCameraModuleByCamNo(camConf.CamNo);
                    if (camera == null)
                    {
                        status.Code = MT_MODULE_DISABLE;
                        status.ErrString = strLog + $"运动失败(模组未知).";
                        Logout($"{status.ErrString}");
                        return status;
                    }

                    if (camera.ModuleTaskState() != ModuleTaskStateE.Idle)
                    {
                        status.Code = MT_CMD_INVALID;
                        status.ErrString = strLog + $"运动失败(模组非空闲状态)";
                        Logout($"{status.ErrString}");
                        return status;
                    }
                    if (axis == AxisE.X)
                    {
                        camera.AxisX.MoveStop();
                    }
                    if (axis == AxisE.Y)
                    {
                        camera.AxisY.MoveStop();
                    }
                    break;
                case AxisE.T:
                case AxisE.W:
                    ConveyorModule conveyor = GetConveyorModuleByCamNo(camConf.CamNo);
                    if (conveyor == null)
                    {
                        status.Code = MT_MODULE_DISABLE;
                        status.ErrString = strLog + $"运动失败(模组未知)";
                        Logout($"{status.ErrString}");
                        return status;
                    }
                    if (conveyor.ModuleTaskState() != ModuleTaskStateE.Idle)
                    {
                        status.Code = MT_CMD_INVALID;
                        status.ErrString = strLog + $"运动失败(模组非空闲状态)";
                        Logout($"{status.ErrString}");
                        return status;
                    }
                    if (axis == AxisE.T)
                    {
                        conveyor.AxisT.MoveStop();
                    }
                    if (axis == AxisE.W)
                    {
                        conveyor.AxisW.MoveStop();
                    }
                    break;
                default:
                    break;
            }

            Logout(strLog);
            return status;
        }
        /// <summary>
        /// 轴回零运动
        /// </summary>
        /// <param name="axis"></param>
        /// <returns></returns>
        public MT_Status MT_MoveHome(CameraConf camConf, AxisE axis)
        {
            MT_Status status = new MT_Status();
            status.Code = MT_OK;

            string strLog = $"{camConf.CamName}模组{axis}轴收到回零运动,";
            switch (axis)
            {
                case AxisE.X:
                case AxisE.Y:
                    CameraModule camera = GetCameraModuleByCamNo(camConf.CamNo);
                    if (camera == null)
                    {
                        status.Code = MT_MODULE_DISABLE;
                        status.ErrString = strLog + $"运动失败(模组未知).";
                        Logout($"{status.ErrString}");
                        return status;
                    }

                    if (camera.ModuleTaskState() != ModuleTaskStateE.Idle)
                    {
                        status.Code = MT_CMD_INVALID;
                        status.ErrString = strLog + $"运动失败(模组非空闲状态)";
                        Logout($"{status.ErrString}");
                        return status;
                    }
                    if (axis == AxisE.X)
                    {
                        camera.AxisX.MoveHome();
                    }
                    if (axis == AxisE.Y)
                    {
                        camera.AxisY.MoveHome();
                    }
                    break;
                case AxisE.T:
                case AxisE.W:
                    ConveyorModule conveyor = GetConveyorModuleByCamNo(camConf.CamNo);
                    if (conveyor == null)
                    {
                        status.Code = MT_MODULE_DISABLE;
                        status.ErrString = strLog + $"运动失败(模组未知)";
                        Logout($"{status.ErrString}");
                        return status;
                    }
                    if (conveyor.ModuleTaskState() != ModuleTaskStateE.Idle)
                    {
                        status.Code = MT_CMD_INVALID;
                        status.ErrString = strLog + $"运动失败(模组非空闲状态)";
                        Logout($"{status.ErrString}");
                        return status;
                    }
                    if (axis == AxisE.T)
                    {
                        conveyor.AxisT.MoveHome();
                    }
                    if (axis == AxisE.W)
                    {
                        if (conveyor.IsHasBoard())
                        {
                            status.Code = MT_CMD_INVALID;
                            status.ErrString = strLog + $"运动失败(传送带有板)";
                            Logout($"{status.ErrString}");
                            return status;
                        }

                        conveyor.AxisW.MoveHome();
                    }
                    break;
                default:
                    break;
            }

            Logout(strLog);
            return status;
        }

        /// <summary>
        /// 获取轴当前位置
        /// </summary>
        /// <param name="axis"></param>
        /// <returns></returns>
        public MT_Status MT_GetAxisPosition(CameraConf camConf, AxisE axis, ref double fpos)
        {
            MT_Status status = new MT_Status();
            status.Code = MT_OK;

            switch (axis)
            {
                case AxisE.X:
                case AxisE.Y:
                    CameraModule camera = GetCameraModuleByCamNo(camConf.CamNo);
                    if (camera == null)
                    {
                        status.Code = MT_MODULE_DISABLE;
                        status.ErrString = $"{axis}轴收到读取位置," + $"失败(模组未知).";
                        Logout($"{status.ErrString}");
                        return status;
                    }

                    if (axis == AxisE.X)
                    {
                        if (0 != camera.AxisX.GetPositionUnit(ref fpos))
                        {
                            string strLog = $"{axis}轴收到读取位置,";
                            status.Code = MT_MOVE_POINT_NOTSUP;
                            status.ErrString = strLog + $"失败(不支持位置模式)";
                            return status;
                        }
                    }
                    if (axis == AxisE.Y)
                    {
                        if (0 != camera.AxisY.GetPositionUnit(ref fpos))
                        {
                            string strLog = $"{axis}轴收到读取位置,";
                            status.Code = MT_MOVE_POINT_NOTSUP;
                            status.ErrString = strLog + $"失败(不支持位置模式)";
                            return status;
                        }
                    }
                    break;
                case AxisE.T:
                case AxisE.W:
                    ConveyorModule conveyor = GetConveyorModuleByCamNo(camConf.CamNo);
                    if (conveyor == null)
                    {
                        status.Code = MT_MODULE_DISABLE;
                        status.ErrString = $"{axis}轴收到读取位置," + $"运动失败(模组未知)";
                        Logout($"{status.ErrString}");
                        return status;
                    }

                    if (axis == AxisE.T)
                    {
                        if (0 != conveyor.AxisT.GetPositionUnit(ref fpos))
                        {
                            string strLog = $"{axis}轴收到读取位置,";
                            status.Code = MT_MOVE_POINT_NOTSUP;
                            status.ErrString = strLog + $"失败(不支持位置模式)";
                            return status;
                        }
                    }
                    if (axis == AxisE.W)
                    {
                        if (0 != conveyor.AxisW.GetPositionUnit(ref fpos))
                        {
                            string strLog = $"{axis}轴收到读取位置,";
                            status.Code = MT_MOVE_POINT_NOTSUP;
                            status.ErrString = strLog + $"失败(不支持位置模式)";
                            return status;
                        }
                    }
                    break;
                default:
                    break;
            }

            return status;
        }
        /// <summary>
        /// 获取轴当前速度
        /// </summary>
        /// <param name="axis"></param>
        /// <returns></returns>
        public MT_Status MT_GetAxisSpeed(CameraConf camConf, AxisE axis, ref double fspeed)
        {
            MT_Status status = new MT_Status();
            status.Code = MT_OK;

            switch (axis)
            {
                case AxisE.X:
                case AxisE.Y:
                    CameraModule camera = GetCameraModuleByCamNo(camConf.CamNo);
                    if (camera == null)
                    {
                        status.Code = MT_MODULE_DISABLE;
                        status.ErrString = $"{camConf.CamName}模组{axis}轴收到读取速度," + $"失败(模组未知).";
                        Logout($"{status.ErrString}");
                        return status;
                    }

                    if (axis == AxisE.X)
                    {
                        camera.AxisX.GetVpSpeed(ref fspeed);
                        
                    }
                    if (axis == AxisE.Y)
                    {
                        camera.AxisY.GetVpSpeed(ref fspeed);
                    }
                    break;
                case AxisE.T:
                case AxisE.W:
                    ConveyorModule conveyor = GetConveyorModuleByCamNo(camConf.CamNo);
                    if (conveyor == null)
                    {
                        status.Code = MT_MODULE_DISABLE;
                        status.ErrString = $"{camConf.CamName}模组{axis}轴收到读取位置," + $"运动失败(模组未知)";
                        Logout($"{status.ErrString}");
                        return status;
                    }

                    if (axis == AxisE.T)
                    {
                        conveyor.AxisT.GetVpSpeed(ref fspeed);
                    }
                    if (axis == AxisE.W)
                    {
                        conveyor.AxisW.GetVpSpeed(ref fspeed);
                    }
                    break;
                default:
                    break;
            }

            return status;
        }
        /// <summary>
        /// 单拍
        /// </summary>
        /// <returns></returns>
        public MT_Status MT_GrabSingleImage(CameraConf conf)
        {
            MT_Status status = new MT_Status();
            status.Code = MT_OK;

            string strLog = $"收到{GetModuleNameByCamNo(conf.CamNo)}模组单拍";
            CameraModule camera = GetCameraModuleByCamNo(conf.CamNo);
            if (camera == null)
            {
                status.Code = MT_MODULE_DISABLE;
                status.ErrString = strLog + $",单拍失败(相机模组未知)";
                Logout(status.ErrString);
                return status;
            }

            camera.GrabSingleImage(conf.LightType);

            return status;
        }
        public MT_Status MT_GrabSingleImageX(CameraConf conf, GrabLightTypeE lightType)
        {
            MT_Status status = new MT_Status();
            status.Code = MT_OK;

            string strLog = $"收到{GetModuleNameByCamNo(conf.CamNo)}模组单拍";
            CameraModule camera = GetCameraModuleByCamNo(conf.CamNo);
            if (camera == null)
            {
                status.Code = MT_MODULE_DISABLE;
                status.ErrString = strLog + $",单拍失败(相机模组未知)";
                Logout(status.ErrString);
                return status;
            }
            Task.Run(() =>
            {
                camera.GrabSingleImage(lightType);
            });
            return status;
        }
        /// <summary>
        /// 单次取图
        /// </summary>
        /// <returns></returns>
        public MT_Status MT_StartGrabImage(CameraConf conf)
        {
            MT_Status status = new MT_Status();
            status.Code = MT_OK;

            string strLog = $"收到{GetModuleNameByCamNo(conf.CamNo)}模组连拍";
            ConveyorModule conveyor = GetConveyorModuleByCamNo(conf.CamNo);
            if (conveyor == null)
            {
                status.Code = MT_MODULE_DISABLE;
                status.ErrString = strLog + $",启动失败(轨道模组未知)";
                Logout(status.ErrString);
                return status;
            }

            if (conveyor.ModuleTaskState() != ModuleTaskStateE.Idle
                   /*&& conveyor.ModuleTaskState() != ModuleTaskStateE.Running*/)
            {
                status.Code = MT_MODULE_DISABLE;
                status.ErrString = strLog + $",启动失败(轨道模组{conveyor.ModuleTaskState()}状态)";
                Logout(status.ErrString);
                return status;
            }

            CameraModule camera = GetCameraModuleByCamNo(conf.CamNo);
            if (camera == null)
            {
                status.Code = MT_MODULE_DISABLE;
                status.ErrString = strLog + $",启动失败(相机模组未知)";
                Logout(status.ErrString);
                return status;
            }

            //if (camera.MapPlan(conf, (ConveyorModuleE)conveyor.ModuleKey, -100000, -100000) != 0)
            //{
            //    status.Code = MT_PATH_FAILED;
            //    status.ErrString = strLog + $",启动失败(路径规划失败)";
            //    Logout(status.ErrString);
            //    return status;
            //}

            //camera.SetPosGrabLight((ConveyorModuleE)conveyor.ModuleKey, conf.GrabPoints);

            if (camera.AutoStart(CameraWorkModeE.Manual, conveyor.ModuleKey) != 0)
            {
                status.Code = MT_MODULE_DISABLE;
                status.ErrString = strLog + $",启动失败(相机模组{camera.ModuleTaskState()}状态)";
                Logout(status.ErrString);
                return status;
            }

            conveyor.AutoStart(ConveyorWorkModeE.GrabImage, camera.ModuleKey);

            Logout(strLog);
            return status;
        }
        /// <summary>
        /// 轨道进板
        /// </summary>
        /// <returns></returns>
        public MT_Status MT_ConveyorInput(CameraConf conf)
        {
            MT_Status status = new MT_Status();
            status.Code = MT_OK;

            string strLog = $"收到{conf.CamName}模组轨道进板";
            ConveyorModule conveyor = GetConveyorModuleByCamNo(conf.CamNo);
            if (conveyor == null)
            {
                status.Code = AXIS_ERR;
                status.ErrString = strLog + $"进板失败(轨道模组未知)";
                Logout($"{status.ErrString}");
                return status;
            }

            CameraModule camera = GetCameraModuleByCamNo(conf.CamNo);
            if (camera == null)
            {
                status.Code = MT_MODULE_DISABLE;
                status.ErrString = strLog + $",启动失败(相机模组未知)";
                Logout(status.ErrString);
                return status;
            }

            camera.MoveToBasePoint();

            if (conveyor.AutoStart(ConveyorWorkModeE.Input, camera.ModuleKey) != 0)
            {
                status.Code = MT_CMD_INVALID;
                status.ErrString = strLog + $",操作无效(模组非空闲状态)";
                Logout(status.ErrString);
                return status;
            }

            Logout(strLog);

            return status;
        }
        /// <summary>
        /// 轨道出板
        /// </summary>
        /// <returns></returns>
        public MT_Status MT_ConveyorOutput(CameraConf conf)
        {
            MT_Status status = new MT_Status();
            status.Code = MT_OK;

            string strLog = $"收到{conf.CamName}模组轨道出板";
            ConveyorModule conveyor = GetConveyorModuleByCamNo(conf.CamNo);
            if (conveyor == null)
            {
                status.Code = MT_MODULE_DISABLE;
                status.ErrString = strLog + $",出板失败(轨道模组未知)";
                Logout(status.ErrString);
                return status;
            }

            CameraModule camera = GetCameraModuleByCamNo(conf.CamNo);
            if (camera == null)
            {
                status.Code = MT_MODULE_DISABLE;
                status.ErrString = strLog + $",启动失败(相机模组未知)";
                Logout(status.ErrString);
                return status;
            }

            if (camera.ModuleTaskState() == ModuleTaskStateE.Running 
                && camera.CurrentRunningConveyor() == conveyor.ModuleKey)
            {
                status.Code = MT_MODULE_DISABLE;
                status.ErrString = strLog + $",启动失败(相机模组{camera.ModuleTaskState()}状态)";
                Logout(status.ErrString);
                return status;
            }

            camera.MoveToBasePoint();

            if (conveyor.AutoStart(ConveyorWorkModeE.Output, camera.ModuleKey) != 0)
            {
                status.Code = MT_CMD_INVALID;
                status.ErrString = strLog + $",操作无效(模组非空闲状态)";
                Logout(status.ErrString);
                return status;
            }

            Logout(strLog);
            return status;
        }


        /// <summary>
        /// 轨道到上料位
        /// </summary>
        /// <returns></returns>
        public MT_Status MT_ConveyorReturn(CameraConf conf)
        {
            MT_Status status = new MT_Status();
            status.Code = MT_OK;

            string strLog = $"收到{conf.CamName}模组轨道回上料位";
            ConveyorModule conveyor = GetConveyorModuleByCamNo(conf.CamNo);
            if (conveyor == null)
            {
                status.Code = MT_MODULE_DISABLE;
                status.ErrString = strLog + $",回上料位失败(轨道模组未知)";
                Logout(status.ErrString);
                return status;
            }

            CameraModule camera = GetCameraModuleByCamNo(conf.CamNo);
            if (camera == null)
            {
                status.Code = MT_MODULE_DISABLE;
                status.ErrString = strLog + $",启动失败(相机模组未知)";
                Logout(status.ErrString);
                return status;
            }

            if (camera.ModuleTaskState() == ModuleTaskStateE.Running
                && camera.CurrentRunningConveyor() == conveyor.ModuleKey)
            {
                status.Code = MT_MODULE_DISABLE;
                status.ErrString = strLog + $",启动失败(相机模组{camera.ModuleTaskState()}状态)";
                Logout(status.ErrString);
                return status;
            }

            camera.MoveToBasePoint();

            if (conveyor.AutoStart(ConveyorWorkModeE.ReturnPut, camera.ModuleKey) != 0)
            {
                status.Code = MT_CMD_INVALID;
                status.ErrString = strLog + $",操作无效(模组非空闲状态)";
                Logout(status.ErrString);
                return status;
            }

            Logout(strLog);
            return status;
        }

        /// <summary>
        /// 开始单次检测
        /// </summary>
        /// <param name="length"></param>
        /// <param name="width"></param>
        /// <param name="cbgrabend"></param>
        /// <returns></returns>
        public MT_Status MT_StartSingleDetect(List<CameraConf> confs)
        {
            MT_Status status = new MT_Status();
            status.Code = MT_OK;

            for (int i = 0; i < confs.Count; i++)
            {
                string strLog = $"收到{GetModuleNameByCamNo(confs[i].CamNo)}模组启动单次检测";
                ConveyorModule conveyor = GetConveyorModuleByCamNo(confs[i].CamNo);
                if (conveyor == null)
                {
                    status.Code = MT_MODULE_DISABLE;
                    status.ErrString = strLog + $",启动失败(轨道模组未知)";
                    Logout(status.ErrString);
                    return status;
                }

                if (conveyor.ModuleTaskState() != ModuleTaskStateE.Idle
                    && conveyor.ModuleTaskState() != ModuleTaskStateE.Running)
                {
                    status.Code = MT_MODULE_DISABLE;
                    status.ErrString = strLog + $",启动失败(轨道模组{conveyor.ModuleTaskState()}状态)";
                    Logout(status.ErrString);
                    return status;
                }

                CameraModule camera = GetCameraModuleByCamNo(confs[i].CamNo);
                if (camera == null)
                {
                    status.Code = MT_MODULE_DISABLE;
                    status.ErrString = strLog + $",启动失败(相机模组未知)";
                    Logout(status.ErrString);
                    return status;
                }

                //if (camera.ModuleTaskState() != ModuleTaskStateE.Idle
                //    /*&& camera.ModuleTaskState() != ModuleTaskStateE.Running*/)
                //{
                //    status.Code = MT_MODULE_DISABLE;
                //    status.ErrString = strLog + $",启动失败(相机模组{camera.ModuleTaskState()}状态)";
                //    Logout(status.ErrString);
                //    return status;
                //}

                if (camera.MapPlan(confs[i], (ConveyorModuleE)conveyor.ModuleKey, -100000, -100000) != 0)
                {
                    status.Code = MT_PATH_FAILED;
                    status.ErrString = strLog + $",启动失败(路径规划失败)";
                    Logout(status.ErrString);
                    //return status;
                }
            }

            for (int i = 0; i < confs.Count; i++)
            {
                string strLog = $"收到{GetModuleNameByCamNo(confs[i].CamNo)}模组启动单次检测";
                ConveyorModule conveyor = GetConveyorModuleByCamNo(confs[i].CamNo);
                CameraModule camera = GetCameraModuleByCamNo(confs[i].CamNo);

                camera.SetPosGrabLight((ConveyorModuleE)conveyor.ModuleKey, confs[i].GrabPoints);
                if (camera.AutoStart(CameraWorkModeE.Manual, conveyor.ModuleKey) != 0)
                {
                    status.Code = MT_MODULE_DISABLE;
                    status.ErrString = strLog + $",启动失败(相机模组非空闲状态)";
                    Logout(status.ErrString);
                    return status;
                }

                if (conveyor.AutoStart(ConveyorWorkModeE.SingleDetect, camera.ModuleKey) != 0)
                {
                    camera.AutoStop(conveyor.ModuleKey);
                    status.Code = MT_MODULE_DISABLE;
                    status.ErrString = strLog + $",启动失败(轨道模组非空闲状态)";
                    Logout(status.ErrString);
                    return status;
                }

                Logout(strLog);
            }
            return status;
        }
        /// <summary>
        /// 停止单次检测
        /// </summary>
        /// <param name="confs"></param>
        /// <returns></returns>
        public MT_Status MT_StopSingleDetect(List<CameraConf> confs)
        {
            MT_Status status = new MT_Status();
            status.Code = MT_OK;

            for (int i = 0; i < confs.Count; i++)
            {
                string strLog = $"收到{GetModuleNameByCamNo(confs[i].CamNo)}模组停止单次检测";
                ConveyorModule conveyor = GetConveyorModuleByCamNo(confs[i].CamNo);
                CameraModule camera = GetCameraModuleByCamNo(confs[i].CamNo);

                if (conveyor.AutoStop(camera.ModuleKey) != 0)
                {
                    Logout($"{strLog},停止失败(轨道停止失败)");
                }
                else if (camera.AutoStop(conveyor.ModuleKey) != 0)
                {
                    Logout($"{strLog},停止失败(相机停止失败)");
                }
                else
                {
                    Logout(strLog);
                }
            }

            return status;
        }
        /// <summary>
        /// 注册模组状态回调
        /// </summary>
        /// <param name="statusNotifyEvent"></param>
        /// <returns></returns>
        public MT_Status RegisterModuleStateCallback(Action<int, ModuleTaskStateE> stateCallback)
        {
            MT_Status status = new MT_Status();
            status.Code = MT_OK;

            moduleStateCallback = stateCallback;

            return status;
        }
        /// <summary>
        /// 获取产品地图
        /// </summary>
        /// <param name="conf"></param>
        /// <returns></returns>
        public MT_Status MT_GetProductAttri(CameraConf camConf, float startx, float starty)
        {
            MT_Status status = new MT_Status();
            status.Code = MT_OK;

            if (camConf == null)
            {
                status.Code = MT_MODULE_DISABLE;
                status.ErrString = $"相机信息获取失败";
                return status;
            }

            CameraModule camera = GetCameraModuleByCamNo(camConf.CamNo);
            if (camera == null)
            {
                status.Code = MT_MODULE_DISABLE;
                status.ErrString = $"拍照路径规划失败（相机）";
                return status;
            }

            ConveyorModule conveyor = GetConveyorModuleByCamNo(camConf.CamNo);
            if (conveyor == null)
            {
                status.Code = MT_MODULE_DISABLE;
                status.ErrString = $"拍照路径规划失败（轴卡）";
                Logout(status.ErrString);
                return status;
            }

            if (camera.MapPlan(camConf, (ConveyorModuleE)conveyor.ModuleKey, startx, starty) != 0)
            {
                status.Code = MT_PATH_FAILED;
                status.ErrString = $"拍照路径规划失败";
                Logout(status.ErrString);
                return status;
            }

            return status;
        }
        /// <summary>
        /// 开始检测
        /// </summary>
        /// <param name="length"></param>
        /// <param name="width"></param>
        /// <param name="cbgrabend"></param>
        /// <returns></returns>
        public MT_Status MT_StartDetect(List<CameraConf> confs)
        {
            MT_Status status = new MT_Status();
            status.Code = MT_OK;
            for (int i = 0; i < confs.Count; i++)
            {
                string strLog = $"收到{GetModuleNameByCamNo(confs[i].CamNo)}模组启动检测";
                ConveyorModule conveyor = GetConveyorModuleByCamNo(confs[i].CamNo);
                if (conveyor == null)
                {
                    status.Code = MT_MODULE_DISABLE;
                    status.ErrString = strLog + $",启动失败(轨道模组未知)";
                    Logout(status.ErrString);
                    return status;
                }

                if (conveyor.ModuleTaskState() != ModuleTaskStateE.Idle
                    && conveyor.ModuleTaskState() != ModuleTaskStateE.Running)
                {
                    status.Code = MT_MODULE_DISABLE;
                    status.ErrString = strLog + $",启动失败({conveyor.ModuleTaskState()}状态)";
                    Logout(status.ErrString);
                    return status;
                }

                CameraModule camera = GetCameraModuleByCamNo(confs[i].CamNo);
                if (camera == null)
                {
                    status.Code = MT_MODULE_DISABLE;
                    status.ErrString = strLog + $",启动失败(相机模组未知)";
                    Logout(status.ErrString);
                    return status;
                }

                //if (camera.ModuleTaskState() != ModuleTaskStateE.Idle
                //    && camera.ModuleTaskState() != ModuleTaskStateE.Running)
                //{
                //    status.Code = MT_MODULE_DISABLE;
                //    status.ErrString = strLog + $",启动失败({camera.ModuleTaskState()}状态)";
                //    Logout(status.ErrString);
                //    return status;
                //}

                if (camera.MapPlan(confs[i], (ConveyorModuleE)conveyor.ModuleKey, -100000, -100000) != 0)
                {
                    status.Code = MT_PATH_FAILED;
                    status.ErrString = strLog + $",启动失败(路径规划失败)";
                    Logout(status.ErrString);
                    return status;
                }
            }

            for (int i = 0; i < confs.Count; i++)
            {
                string strLog = $"收到{GetModuleNameByCamNo(confs[i].CamNo)}模组启动检测";
                ConveyorModule conveyor = GetConveyorModuleByCamNo(confs[i].CamNo);
                CameraModule camera = GetCameraModuleByCamNo(confs[i].CamNo);

                camera.SetPosGrabLight((ConveyorModuleE)conveyor.ModuleKey, confs[i].GrabPoints);

                if (camera.AutoStart(CameraWorkModeE.Detect, conveyor.ModuleKey) != 0)
                {
                    status.Code = MT_MODULE_DISABLE;
                    status.ErrString = strLog + $",启动失败(相机模组非空闲状态)";
                    Logout(status.ErrString);
                    return status;
                }

                if (conveyor.AutoStart(ConveyorWorkModeE.Detect, camera.ModuleKey) != 0)
                {
                    camera.AutoStop(conveyor.ModuleKey);
                    status.Code = MT_MODULE_DISABLE;
                    status.ErrString = strLog + $",启动失败(轨道模组非空闲状态)";
                    Logout(status.ErrString);
                    return status;
                }

                Logout(strLog);
            };
            return status;
        }
        /// <summary>
        /// 暂停检测
        /// </summary>
        /// <returns></returns>
        public MT_Status MT_PauseDetect(List<CameraConf> confs)
        {
            MT_Status status = new MT_Status();
            status.Code = MT_OK;

            

            return status;
        }
        /// <summary>
        /// 停止检测
        /// </summary>
        /// <returns></returns>
        public MT_Status MT_StopDetect(List<CameraConf> confs)
        {
            MT_Status status = new MT_Status();
            status.Code = MT_OK;

            for (int i = 0; i < confs.Count; i++)
            {
                string strLog = $"收到{GetModuleNameByCamNo(confs[i].CamNo)}模组停止检测";
                ConveyorModule conveyor = GetConveyorModuleByCamNo(confs[i].CamNo);
                if (conveyor == null)
                {
                    status.Code = MT_MODULE_DISABLE;
                    status.ErrString = strLog + $",停止失败(轨道模组未知)";
                    Logout(status.ErrString);
                    break;
                }

                CameraModule camera = GetCameraModuleByCamNo(confs[i].CamNo);
                if (camera == null)
                {
                    status.Code = MT_MODULE_DISABLE;
                    status.ErrString = strLog + $",停止失败(相机模组未知)";
                    Logout(status.ErrString);
                    return status;
                }

                camera.AutoStop(conveyor.ModuleKey);
                conveyor.AutoStop(camera.ModuleKey);
            };

            return status;
        }

        /// <summary>
        /// 直通
        /// </summary>
        /// <param name="length"></param>
        /// <param name="width"></param>
        /// <param name="cbgrabend"></param>
        /// <returns></returns>
        public MT_Status MT_PassDetect(List<CameraConf> confs)
        {
            MT_Status status = new MT_Status();
            status.Code = MT_OK;
            for (int i = 0; i < confs.Count; i++)
            {
                string strLog = $"收到{GetModuleNameByCamNo(confs[i].CamNo)}模组启动检测";
                ConveyorModule conveyor = GetConveyorModuleByCamNo(confs[i].CamNo);
                if (conveyor == null)
                {
                    status.Code = MT_MODULE_DISABLE;
                    status.ErrString = strLog + $",启动失败(轨道模组未知)";
                    Logout(status.ErrString);
                    return status;
                }

                if (conveyor.ModuleTaskState() != ModuleTaskStateE.Idle
                    && conveyor.ModuleTaskState() != ModuleTaskStateE.Running)
                {
                    status.Code = MT_MODULE_DISABLE;
                    status.ErrString = strLog + $",启动失败({conveyor.ModuleTaskState()}状态)";
                    Logout(status.ErrString);
                    return status;
                }

                CameraModule camera = GetCameraModuleByCamNo(confs[i].CamNo);
                if (camera == null)
                {
                    status.Code = MT_MODULE_DISABLE;
                    status.ErrString = strLog + $",启动失败(相机模组未知)";
                    Logout(status.ErrString);
                    return status;
                }

                //if (camera.ModuleTaskState() != ModuleTaskStateE.Idle
                //    && camera.ModuleTaskState() != ModuleTaskStateE.Running)
                //{
                //    status.Code = MT_MODULE_DISABLE;
                //    status.ErrString = strLog + $",启动失败({camera.ModuleTaskState()}状态)";
                //    Logout(status.ErrString);
                //    return status;
                //}

                if (camera.MapPlan(confs[i], (ConveyorModuleE)conveyor.ModuleKey, -100000, -100000) != 0)
                {
                    status.Code = MT_PATH_FAILED;
                    status.ErrString = strLog + $",启动失败(路径规划失败)";
                    Logout(status.ErrString);
                    return status;
                }
            }

            for (int i = 0; i < confs.Count; i++)
            {
                string strLog = $"收到{GetModuleNameByCamNo(confs[i].CamNo)}模组启动检测";
                ConveyorModule conveyor = GetConveyorModuleByCamNo(confs[i].CamNo);
                CameraModule camera = GetCameraModuleByCamNo(confs[i].CamNo);

                camera.SetPosGrabLight((ConveyorModuleE)conveyor.ModuleKey, confs[i].GrabPoints);

                if (camera.AutoStart(CameraWorkModeE.Detect, conveyor.ModuleKey) != 0) 
                {
                    status.Code = MT_MODULE_DISABLE;
                    status.ErrString = strLog + $",启动失败(相机模组非空闲状态)";
                    Logout(status.ErrString);
                    return status;
                }

                if (conveyor.AutoStart(ConveyorWorkModeE.PassModeRun, camera.ModuleKey) != 0)
                {
                    camera.AutoStop(conveyor.ModuleKey);
                    status.Code = MT_MODULE_DISABLE;
                    status.ErrString = strLog + $",启动失败(轨道模组非空闲状态)";
                    Logout(status.ErrString);
                    return status;
                }

                Logout(strLog);
            };
            return status;
        }


        /// <summary>
        /// 设置检测结果模式，是否输出NG信号？
        /// </summary>
        /// <param name="isEnable">0-默认不启用 1-模式1 2-模式2</param>
        /// <returns></returns>
        public MT_Status MT_SetCheckResultMode(CameraConf conf, int mode)
        {

            MT_Status status = new MT_Status();
            status.Code = MT_OK;

            if (conf == null)
            {
                status.Code = MT_CAMERA_NOT_INIT;
                return status;
            }
            string strLog = $"收到{GetModuleNameByCamNo(conf.CamNo)}检测结果模式:{mode}";
            ConveyorModule conveyor = GetConveyorModuleByCamNo(conf.CamNo);
            if (conveyor == null)
            {
                status.Code = MT_MODULE_DISABLE;
                status.ErrString = strLog + $",失败(轨道模组未知)";
                Logout(status.ErrString);
                return status;
            }

            conveyor.SetCheckResultMode(mode);

            HardwareConfi.Instance.SetConveyorSmemaMode((ConveyorModuleE)conveyor.ModuleKey, mode);
            return status;
        }
        /// <summary>
        /// 设置检测结果，输出NG信号
        /// </summary>
        /// <param name="pid"></param>
        /// <param name="isNG"></param>
        /// <returns></returns>
        public MT_Status MT_SetCheckResultValue(CameraConf conf, string pid, bool isNG)
        {
            MT_Status status = new MT_Status();
            status.Code = MT_OK;
            if (conf == null)
            {
                status.Code = MT_CAMERA_NOT_INIT;
                return status;
            }
            string strLog = $"收到{GetModuleNameByCamNo(conf.CamNo)}ID:{pid}检测结果NG:{isNG}";
            ConveyorModule conveyor = GetConveyorModuleByCamNo(conf.CamNo);
            if (conveyor == null)
            {
                status.Code = MT_MODULE_DISABLE;
                status.ErrString = strLog + $",输出NG信号失败(轨道模组未知)";
                Logout(status.ErrString);
                return status;
            }
            CameraModule camera = GetCameraModuleByCamNo(conf.CamNo);
            if (camera == null)
            {
                status.Code = MT_MODULE_DISABLE;
                status.ErrString = strLog + $",输出NG信号失败(相机模组未知)";
                return status;
            }

            Logout($"SetCheckResultVaule:{camera.ModuleKey}.");
            conveyor.SetCheckResultVaule(camera.ModuleKey, pid, isNG);

            return status;
        }

        public MT_Status MT_WantGrab(CameraConf conf)
        {
            MT_Status status = new MT_Status();
            status.Code = MT_OK;

            if (conf == null)
            {
                status.Code = MT_CAMERA_NOT_INIT;
                return status;
            }
            string strLog = $"收到{GetModuleNameByCamNo(conf.CamNo)}想要采集指令";
            ConveyorModule conveyor = GetConveyorModuleByCamNo(conf.CamNo);
            if (conveyor == null)
            {
                status.Code = MT_MODULE_DISABLE;
                status.ErrString = strLog + $",失败(轨道模组未知)";
                Logout(status.ErrString);
                return status;
            }
            if(!conveyor.CanGrab())
            {
                status.Code = MT_MODULE_NOT_READY;
            }
            CameraModule camera = GetCameraModuleByCamNo(conf.CamNo);
            if (!camera.ReadyGrab())
            {
                status.Code = MT_MODULE_NOT_READY;
            }
            return status;
        }
        public MT_Status MT_StartGrab(CameraConf conf)
        {
            MT_Status status = new MT_Status();
            status.Code = MT_OK;

            if (conf == null)
            {
                status.Code = MT_CAMERA_NOT_INIT;
                return status;
            }
            string strLog = $"收到{GetModuleNameByCamNo(conf.CamNo)}想要采集指令";
            ConveyorModule conveyor = GetConveyorModuleByCamNo(conf.CamNo);
            if (conveyor == null)
            {
                status.Code = MT_MODULE_DISABLE;
                status.ErrString = strLog + $",失败(轨道模组未知)";
                Logout(status.ErrString);
                return status;
            }
            if (!conveyor.StartGrab())
            {
                status.Code = MT_MODULE_DISABLE;
                status.ErrString = strLog + $",失败(轨道启动采集失败)";
                Logout(status.ErrString);
                status.Code = MT_MODULE_GRAB_FAILED;
            }
            return status;
        }
        public MT_Status MT_GrabOver(CameraConf conf)
        {
            MT_Status status = new MT_Status();
            status.Code = MT_OK;

            if (conf == null)
            {
                status.Code = MT_CAMERA_NOT_INIT;
                return status;
            }
            CameraModule camera = GetCameraModuleByCamNo(conf.CamNo);
            if (!camera.GrabOver())
            {
                status.Code = MT_MODULE_NOT_READY;
            }
            return status;
        }
        public MT_Status MT_GetGrabRoundCount(CameraConf conf, out UInt32 gcount)
        {
            MT_Status status = new MT_Status();
            status.Code = MT_OK;
            gcount = 0;
            if (conf == null)
            {
                status.Code = MT_CAMERA_NOT_INIT;
                return status;
            }
            CameraModule camera = GetCameraModuleByCamNo(conf.CamNo);
            if (camera == null)
            {
                status.Code = MT_MODULE_DISABLE;
                return status;
            }
            gcount = camera.GrabRoundCount();
            return status;
        }

        /// <summary>
        /// 注册检测结果异常回调
        /// </summary>
        /// <param name="exceptionCallback"></param>
        /// <returns></returns>
        public MT_Status MT_RegisterCheckResultException(CameraConf conf, Action<string> exceptionCallback)
        {
            MT_Status status = new MT_Status();
            status.Code = MT_OK;

            ConveyorModule conveyor = GetConveyorModuleByCamNo(conf.CamNo);
            if (conveyor == null)
            {
                status.Code = MT_MODULE_DISABLE;
                status.ErrString = $"注册检测结果异常失败(轨道模组未知)";
                Logout(status.ErrString);
                return status;
            }

            conveyor.CheckResultCallback = exceptionCallback;

            return status;
        }
        /// <summary>
        /// 设置轴软限位
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="limitN"></param>
        /// <param name="limitP"></param>
        /// <returns></returns>
        public MT_Status SetAxisLimit(AxisEnum axis, float limitN, float limitP)
        {
            MT_Status status = new MT_Status();
            status.Code = MT_OK;

            HardwareConfi.Instance.SetAxisLimit(axis, limitN, limitP);
            Logout($"设置{axis}轴软限位:{limitN},{limitP}.");
            return status;
        }
        /// <summary>
        /// 获取轴软限位
        /// </summary>
        /// <param name="axis"></param>
        /// <param name="limitN"></param>
        /// <param name="limitP"></param>
        /// <returns></returns>
        public MT_Status GetAxisLimit(AxisEnum axis, ref float limitN, ref float limitP)
        {
            MT_Status status = new MT_Status();
            status.Code = MT_OK;

            HardwareConfi.Instance.GetAxisLimit(axis, ref limitN, ref limitP);
            Logout($"获取{axis}轴软限位:{limitN},{limitP}.");

            return status;
        }
        /// <summary>
        /// 设置相机标定起点
        /// </summary>
        /// <param name="conveyor"></param>
        /// <param name="cameraMdl"></param>
        /// <param name="xpos"></param>
        /// <param name="ypos"></param>
        /// <returns></returns>
        public MT_Status SetCameraCalibration(ConveyorModuleE conveyor, CameraModuleE cameraMdl, float xpos, float ypos)
        {
            MT_Status status = new MT_Status();
            status.Code = MT_OK;

            HardwareConfi.Instance.SetCameraCalibration(conveyor, cameraMdl, xpos, ypos);
            Logout($"设置{conveyor}轨道拍照起点:{xpos},{ypos}.");

            return status;
        }
        /// <summary>
        /// 获取相机标定起点
        /// </summary>
        /// <param name="conveyorMdl"></param>
        /// <param name="cameraMdl"></param>
        /// <param name="xpos"></param>
        /// <param name="ypos"></param>
        /// <returns></returns>
        public MT_Status GetCameraCalibration(ConveyorModuleE conveyor, CameraModuleE cameraMdl, ref float xpos, ref float ypos)
        {
            MT_Status status = new MT_Status();
            status.Code = MT_OK;

            HardwareConfi.Instance.GetCameraCalibration(conveyor, cameraMdl, ref xpos, ref ypos);
            Logout($"获取{conveyor}轨道拍照起点:{xpos},{ypos}.");

            return status;
        }
        /// <summary>
        /// 设置读码器启用状态
        /// </summary>
        /// <param name="conf">模组</param>
        /// <param name="enable">0-禁用 1-启用</param>
        /// <returns></returns>
        public MT_Status MT_SetCodeReaderEnable(CameraConf conf, int enable)
        {
            MT_Status status = new MT_Status();
            status.Code = MT_OK;

            ConveyorModule conveyor = GetConveyorModuleByCamNo(conf.CamNo);
            if (conveyor == null)
            {
                status.Code = MT_MODULE_DISABLE;
                status.ErrString = $"设置读码器启用状态失败(轨道模组未知)";
                Logout(status.ErrString);
                return status;
            }

            HardwareConfi.Instance.SetCodeReaderState((ConveyorModuleE)conveyor.ModuleKey, enable);
            
            return status;
        }
        /// <summary>
        /// 获取读码器启用状态
        /// </summary>
        /// <param name="conf">模组</param>
        /// <param name="enable">0-禁用 1-启用</param>
        /// <returns></returns>
        public MT_Status MT_GetCodeReaderEnable(CameraConf conf, ref int enable)
        {
            MT_Status status = new MT_Status();
            status.Code = MT_OK;
            ConveyorModule conveyor = GetConveyorModuleByCamNo(conf.CamNo);
            if (conveyor == null)
            {
                status.Code = MT_MODULE_DISABLE;
                status.ErrString = $"获取读码器启用状态失败(轨道模组未知)";
                Logout(status.ErrString);
                return status;
            }

            HardwareConfi.Instance.GetCodeReaderState((ConveyorModuleE)conveyor.ModuleKey, ref enable);

            return status;
        }
        /// <summary>
        /// 注册条码事件
        /// </summary>
        /// <param name="codeReaderCallback"></param>
        /// <returns></returns>
        public MT_Status MT_RegisterCodeReaderCallback(Action<int, string> codeReaderCallback)
        {
            MT_Status status = new MT_Status();
            status.Code = MT_OK;

            conveyorModules.ForEach(itm =>
            {
                itm.CodeReaderCallback = codeReaderCallback;
            });

            return status;
        }
        /// <summary>
        /// 设置条码校验结果
        /// </summary>
        /// <param name="conf"></param>
        /// <param name="result">0-失败 1-成功</param>
        /// <returns></returns>
        public MT_Status MT_SetCodeReaderCheckResult(CameraConf conf, int result)
        {
            MT_Status status = new MT_Status();
            status.Code = MT_OK;

            ConveyorModule conveyor = GetConveyorModuleByCamNo(conf.CamNo);
            if (conveyor == null)
            {
                status.Code = MT_MODULE_DISABLE;
                status.ErrString = $"设置读码校验结果失败(轨道模组未知)";
                Logout(status.ErrString);
                return status;
            }

            conveyor.SetQrCodeCheckResult(result);

            return status;
        }
        /// <summary>
        /// 清除条码报警
        /// </summary>
        /// <param name="conf"></param>
        /// <returns></returns>
        public MT_Status MT_ClearCodeReaderAlarm(CameraConf conf)
        {
            MT_Status status = new MT_Status();
            status.Code = MT_OK;

            ConveyorModule conveyor = GetConveyorModuleByCamNo(conf.CamNo);
            if (conveyor == null)
            {
                status.Code = MT_MODULE_DISABLE;
                status.ErrString = $"清除读码报警失败(轨道模组未知)";
                Logout(status.ErrString);
                return status;
            }

            conveyor.ClearQrCodeAlarm();

            return status;
        }

        /// <summary>
        /// 注册报警事件回调
        /// </summary>
        /// <param name="AlmEvent"></param>
        /// <returns></returns>
        public MT_Status RegisterAlarmEventCallback(Action<AlarmInfo> alarmEventCallback)
        {
            MT_Status status = new MT_Status();
            status.Code = MT_OK;

            AlarmDevice.Instance.RegisterAlarmCallback(alarmEventCallback);

            return status;
        }
        /// <summary>
        /// 设置轨道宽度
        /// </summary>
        /// <returns></returns>
        public MT_Status MT_SetConveyorWidth(CameraConf conf, float width)
        {
            MT_Status status = new MT_Status();
            status.Code = MT_OK;

            string strLog = $"设置{GetModuleNameByCamNo(conf.CamNo)}轨道宽度,";
            var conveyor = GetConveyorModuleByCamNo(conf.CamNo);
            if (conveyor == null)
            {
                status.Code = MT_MODULE_DISABLE;
                status.ErrString = $"{strLog}失败(轨道模组未知)";
                Logout(status.ErrString);
                return status;
            }

            if (0 != conveyor.SetTrackWidth(width))
            {
                status.Code = MT_MAIN_NOT_IDLE;
                status.ErrString = strLog + $"运动失败(非空闲状态)";
                Logout($"{status.ErrString}");
                return status;
            }

            return status;
        }
        /// <summary>
        /// 获取轨道宽度
        /// </summary>
        /// <param name="width"></param>
        /// <returns></returns>
        public MT_Status MT_GetConveyorWidth(CameraConf conf, ref float width)
        {
            MT_Status status = new MT_Status();
            status.Code = MT_OK;

            string strLog = $"获取{GetModuleNameByCamNo(conf.CamNo)}轨道宽度,";
            var conveyor = GetConveyorModuleByCamNo(conf.CamNo);
            if (conveyor == null)
            {
                status.Code = MT_MODULE_DISABLE;
                status.ErrString = $"{strLog}失败(轨道模组未知)";
                Logout(status.ErrString);
                return status;
            }

            conveyor.GetTrackWidth(ref width);

            return status;
        }
        /// <summary>
        /// 设置轨道模组超时
        /// </summary>
        /// <param name="enType"></param>
        /// <param name="strVal"></param>
        /// <returns></returns>
        public MT_Status MT_SetConveyorTimeout(CameraConf conf, int timeout)
        {
            MT_Status status = new MT_Status();
            status.Code = MT_OK;

            ConveyorModule conveyor = GetConveyorModuleByCamNo(conf.CamNo);
            if (conveyor == null)
            {
                status.Code = MT_MODULE_DISABLE;
                status.ErrString = $"设置轨道模组超时失败(轨道模组未知)";
                Logout(status.ErrString);
                return status;
            }

            HardwareConfi.Instance.SetConveyorTimeout((ConveyorModuleE)conveyor.ModuleKey, timeout);
            Logout($"设置{Enum.GetName(typeof(ConveyorModuleE), conveyor.ModuleKey)}轨道模组超时时长：{timeout}.");

            return status;
        }
        /// <summary>
        /// 获取轨道模组超时
        /// </summary>
        /// <param name="module"></param>
        /// <param name="timeout"></param>
        /// <returns></returns>
        public MT_Status MT_GetConveyorTimeout(CameraConf conf, ref int timeout)
        {
            MT_Status status = new MT_Status();
            status.Code = MT_OK;

            ConveyorModule conveyor = GetConveyorModuleByCamNo(conf.CamNo);
            if (conveyor == null)
            {
                status.Code = MT_MODULE_DISABLE;
                status.ErrString = $"获取轨道模组超时失败(轨道模组未知)";
                Logout(status.ErrString);
                return status;
            }

            HardwareConfi.Instance.GetConveyorTimeout((ConveyorModuleE)conveyor.ModuleKey, ref timeout);
            Logout($"获取{Enum.GetName(typeof(ConveyorModuleE), conveyor.ModuleKey)}轨道模组超时时长：{timeout}.");

            return status;
        }
        /// <summary>
        /// 设置轨道模组超时
        /// </summary>
        /// <param name="enType"></param>
        /// <param name="strVal"></param>
        /// <returns></returns>
        public MT_Status MT_SetCameraTimeout(CameraConf conf, int timeout)
        {
            MT_Status status = new MT_Status();
            status.Code = MT_OK;

            CameraModule camera = GetCameraModuleByCamNo(conf.CamNo);
            if (camera == null)
            {
                status.Code = MT_MODULE_DISABLE;
                status.ErrString = $"设置相机组超时失败(相机模组未知)";
                Logout(status.ErrString);
                return status;
            }

            HardwareConfi.Instance.SetCameraTimeout((CameraModuleE)camera.ModuleKey, timeout);
            Logout($"设置{Enum.GetName(typeof(CameraModuleE), camera.ModuleKey)}相机模组超时时长：{timeout}.");

            return status;
        }
        /// <summary>
        /// 获取轨道模组超时
        /// </summary>
        /// <param name="module"></param>
        /// <param name="timeout"></param>
        /// <returns></returns>
        public MT_Status MT_GetCameraTimeout(CameraConf conf, ref int timeout)
        {
            MT_Status status = new MT_Status();
            status.Code = MT_OK;

            CameraModule camera = GetCameraModuleByCamNo(conf.CamNo);
            if (camera == null)
            {
                status.Code = MT_MODULE_DISABLE;
                status.ErrString = $"获取相机组超时失败(相机模组未知)";
                Logout(status.ErrString);
                return status;
            }

            HardwareConfi.Instance.GetCameraTimeout((CameraModuleE)camera.ModuleKey, ref timeout);
            Logout($"获取{Enum.GetName(typeof(CameraModuleE), camera.ModuleKey)}相机模组超时时长：{timeout}.");

            return status;
        }
        /// <summary>
        /// 设置轨道工作模式
        /// </summary>
        /// <param name="mode">0-左进右出 1-右进左出 2-左进左出 3-右进右出</param>
        /// <returns></returns>
        public MT_Status MT_SetConveyorWorkMode(CameraConf conf, int mode)
        {
            MT_Status status = new MT_Status();
            status.Code = MT_OK;

            ConveyorModule conveyor = GetConveyorModuleByCamNo(conf.CamNo);
            if (conveyor == null)
            {
                status.Code = MT_MODULE_DISABLE;
                status.ErrString = $"获取轨道模组超时失败(轨道模组未知)";
                Logout(status.ErrString);
                return status;
            }

            HardwareConfi.Instance.SetConveyorWorkMode((ConveyorModuleE)conveyor.ModuleKey, mode);
            Logout($"设置{Enum.GetName(typeof(ConveyorModuleE), conveyor.ModuleKey)}轨道工作模式:{mode}.");

            return status;
        }
        /// <summary>
        /// 获取传送模式
        /// </summary>
        /// <param name="mode">0-左进右出 1-右进左出 2-左进左出 3-右进右出</param>
        /// <returns></returns>
        public MT_Status MT_GetConveyorWorkMode(CameraConf conf, ref int mode)
        {
            MT_Status status = new MT_Status();
            status.Code = MT_OK;

            ConveyorModule conveyor = GetConveyorModuleByCamNo(conf.CamNo);
            if (conveyor == null)
            {
                status.Code = MT_MODULE_DISABLE;
                status.ErrString = $"获取轨道模组超时失败(轨道模组未知)";
                Logout(status.ErrString);
                return status;
            }
            HardwareConfi.Instance.GetConveyorWorkMode((ConveyorModuleE)conveyor.ModuleKey, ref mode);
            Logout($"获取{Enum.GetName(typeof(ConveyorModuleE), conveyor.ModuleKey)}轨道工作模式:{mode}.");

            return status;
        }
        /// <summary>
        /// 关闭蜂鸣器
        /// </summary>
        /// <returns></returns>
        public MT_Status MT_CloseBeep(CameraConf conf)
        {
            MT_Status status = new MT_Status();
            status.Code = MT_OK;
            Logout($"进入蜂鸣器关闭.");
            ledControls.ForEach(it =>
            {
                it.CloseBeep();
            });

            return status;
        }

        public MT_Status MT_OpenBeep(CameraConf conf)
        {
            MT_Status status = new MT_Status();
            status.Code = MT_OK;
            Logout($"进入蜂鸣器开启.");
            ledControls.ForEach(it =>
            {
                it.OpenBeep();
            });

            return status;
        }


        public MT_Status MT_ChangeSafedoor(bool bUse)
        {
            MT_Status status = new MT_Status();
            MotionDevice.Instance.m_bUseSafedoor = bUse;

            return status;
        }


        /// <summary>
        /// 读取版本信息
        /// </summary>
        /// <param name="ver"></param>
        /// <returns></returns>
        public MT_Status MT_GetVersionInfo(out string ver)
        {
            MT_Status status = new MT_Status();
            status.Code = MT_OK;

            ver = SoftwareVersion;

            return status;
        }
        public MT_Status MTGetAllInputBit(ref uint port, int icardId)
        {
            MT_Status status = new MT_Status();

            port = MotionDevice.Instance.ReadInport(icardId);
            return status;
        }

        public MT_Status MTGetAllOutputBit(ref uint port, int icardId)
        {
            MT_Status status = new MT_Status();
            port = MotionDevice.Instance.ReadOutport(icardId);
            return status;
        }

        public MT_Status MTGetState(
            CameraConf conf, 
            ref long cameraState,
            ref long conveyorState)
        {
            MT_Status status = new MT_Status();
            status.Code = MT_OK;

            ConveyorModule conveyor = GetConveyorModuleByCamNo(conf.CamNo);
            if (conveyor == null)
            {
                status.Code = MT_UNKNOWN;
                return status;
            }

            CameraModule camera = GetCameraModuleByCamNo(conf.CamNo);
            if (camera == null)
            {
                status.Code = MT_UNKNOWN;
                return status;
            }
            camera.GetState(ref cameraState);
            conveyor.GetState(ref conveyorState);
            return status;
        }
    }
}
